<template>
  <div class="uno-container uno-overflow-hidden uno-h-screen uno-bg-green-400 rui_swiper_main"
       ref="touchMain">
    <div class="uno-flex uno-text-xs uno-relative">
      <div v-for="item in titleList" class="uno-p-0.5  title-item" :ref="(el) => titleListDomPush(el)">
        {{ item }}
      </div>
      <div
          class="rui_tab_slider uno-bg-purple-600 uno-absolute"
          ref="sliderMain"
          :style="sliderStyle"
      ></div>
    </div>
    <div
        class="uno-container uno-h-full uno-flex rui_scroll_main"
        :style="transFormX">
      <slot></slot>
    </div>
  </div>
</template>

<script lang="ts" setup>
import type {Ref} from "vue";

const children = ref([]);
provide("setSwiper", children.value);
const childrenLength = computed(() => {
  return children.value.length;
});
// tab标题对象
const titleList = computed(() => {
  return children.value.map((item: any) => {
    return item.props.title;
  });
});
// tab标题dom
const titleListDom: Ref<HTMLDataElement[]> = ref([]);
const titleListDomPush = (el: HTMLDataElement) => {
  titleListDom.value.push(el);
};
// tab内容滚动的距离
const transFormX = computed(() => {
  const {swiperSet} = toRefs(swipeProxy)
  console.log('swiperSet', swiperSet.value.positionX)
  return {
    transform: `translateX(${swiperSet.value.positionX}%) translateY(0)`
  }
});
// tabTitle滑块样式
const sliderStyle = computed(() => {
  const {direction, sliderSet} = toRefs(swipeProxy);
  const {positionX, startX} = toRefs(sliderSet.value)
  console.log(positionX, startX)
  return {
    width: startX.value == 0 ? undefined : `${startX.value}px`,
    left: `${direction.value === "left" ? positionX.value + 'px' : 'unset'}`,
    right: `${direction.value === "right" ? positionX.value + 'px' : 'unset'}`,
  };
});
// 需要滚动的dom 元素
const touchMain: Ref<HTMLDataElement | any> = ref(null);
const sliderMain: Ref<HTMLDataElement | any> = ref(null);
// 设置的元素值
const swipeProxy = reactive({
  swiperIndex: 0, // 标识获取当前的位置
  swiperSet: {
    startX: 0,
    startY: 0,
    positionX: 0,
  },
  sliderSet: {
    startX: 0,
    positionX: 0,
    defaultWidth: 0
  },
  startTime: new Date(),
  direction: "left",
  distanceRatio: 0,
});

function getBoundingClientRect(dom: HTMLDataElement | any) {
  return dom.getBoundingClientRect();
}

function getSliderPosition(dom: any) {
  const touchDom = touchMain.value;
  const touchWidth = touchDom.offsetWidth;
  const {left, width} = getBoundingClientRect(dom)
  const sliderWidth = swipeProxy.sliderSet.defaultWidth
  const rightCenterPoint = touchWidth - left - width / 2 //当前的顶部标题的
  const leftCenterPoint = left + width / 2 //当前的顶部标题的

  return {
    width: width,
    left: leftCenterPoint - sliderWidth / 2,
    right: rightCenterPoint - sliderWidth / 2
  }
}

//
onMounted(() => {
  let touchFlag = false;
  // 设置初始化参数
  const touchDom = touchMain.value;
  const touchWidth = touchDom.offsetWidth;
  const sliderWidth = getBoundingClientRect(sliderMain.value).width;
  const startTitleDom = titleListDom.value[swipeProxy.swiperIndex]
  swipeProxy.sliderSet.startX = sliderWidth
  swipeProxy.sliderSet.defaultWidth = sliderWidth
  swipeProxy.sliderSet.positionX = getSliderPosition(startTitleDom).left;

  function touchStart(event: TouchEvent) {
    touchFlag = true; //设置长按不动
    const touch = event.touches[0]; //获取第一个触点
    const startX = Number(touch.pageX); //页面触点X坐标
    const startY = Number(touch.pageY); //页面触点Y坐标
    const startTime = new Date();
    swipeProxy.swiperSet = Object.assign(swipeProxy.swiperSet, {
      startX,
      startY,
    });
    swipeProxy.distanceRatio = 0;
    swipeProxy.startTime = startTime;
  }

  function touchMove(event: TouchEvent) {
    if (!touchFlag) return;
    const touch = event.touches[0]; //获取第一个触点
    const moveX = Number(touch.pageX); //页面触点X坐标
    const distance = moveX - swipeProxy.swiperSet.startX;
    const direction = distance > 0 ? "right" : "left";
    const lastIndex = childrenLength.value - 1
    // 在第一屏幕左滑动无效
    if (!swipeProxy.swiperIndex && direction === "right") return;
    // 在最后一屏幕右滑动无效
    if (swipeProxy.swiperIndex === lastIndex && direction === "left") return;
    //记录滑动方向
    swipeProxy.direction = direction;
    requestAnimationFrame(() => {
      // 换算出占比
      const Ratio = distance / touchWidth;
      // 不明白
      let transformX = (swipeProxy.swiperIndex + Ratio) * 100;
      const lastPositionX = -lastIndex * 100
      if (transformX >= 0) transformX = 0;
      else if (transformX <= lastPositionX) transformX = lastPositionX;
      swipeProxy.swiperSet.positionX = transformX;
      swipeProxy.distanceRatio = Math.abs(Ratio);
      // 设置顶部title滚动位置
      const titleIndex = Math.abs(swipeProxy.swiperIndex);
      // 获取到要滚动到下一个的位置
      const nextIndex = direction === "right" ? titleIndex - 1 : titleIndex + 1;
      // 计算title之间的距离
      const currentTitleDom = getSliderPosition(titleListDom.value[titleIndex]);
      const nexTitleDom = getSliderPosition(titleListDom.value[nextIndex]);
      // 不明白
      const allNum = (currentTitleDom.width + nexTitleDom.width) / 2 + sliderWidth
      const sliderDistance = swipeProxy.distanceRatio * allNum;
      // 获取元素的宽度
      const startX = sliderWidth + sliderDistance;
      swipeProxy.sliderSet.startX = startX > allNum ? allNum : startX
      const position = getSliderPosition(titleListDom.value[titleIndex]);
      swipeProxy.sliderSet.positionX = position[direction]
    });
  }

  function touchEnd() {
    if (swipeProxy.distanceRatio >= 0.3) {
      swipeProxy.direction === "right" ? swipeProxy.swiperIndex++ : swipeProxy.swiperIndex--;
      swipeProxy.direction = swipeProxy.direction === "right" ? 'left' : 'right'
    }
    requestAnimationFrame(() => {
      console.log(swipeProxy.swiperIndex * 100)
      swipeProxy.swiperSet.positionX = swipeProxy.swiperIndex * 100;
      const position:any = getSliderPosition(titleListDom.value[Math.abs(swipeProxy.swiperIndex)]);
      swipeProxy.sliderSet.positionX = position[swipeProxy.direction]
      requestAnimationFrame(() => {
        swipeProxy.sliderSet.startX = sliderWidth;
      })
      touchFlag = false;
    });
  }

  touchDom.addEventListener("touchstart", touchStart);
  touchDom.addEventListener("touchmove", touchMove);
  touchDom.addEventListener("touchend", touchEnd);
});
</script>

<style lang="less" scoped>
.rui_scroll_main {
  will-change: transform;
  transition: transform 0.3s cubic-bezier(0, 0.75, 0.27, 1);
  //width: auto;
  //display: block;
  //transition-duration: 0.3s;
}

.rui_swiper_main {
  backface-visibility: hidden;
}

.title-item {
  border: solid 1px red;
}

.rui_tab_slider {
  will-change: width;
  transition: width 0.5s cubic-bezier(0, 0.75, 0.27, 1);
  width: 40px;
  height: 10px;
  border-radius: 99px;
  bottom: 0;
  transform-origin: left;
  margin: 0 auto 0 0;
}
</style>
